package parse;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import absyn.Exp;
import errorMsg.ErrorMsg;
import findEscape.FindEscape;


public class CupTest {

	/**
	 * @param args
	 * @throws FileNotFoundException 
	 */
	public static void main(String[] args) throws FileNotFoundException {
		String filename = "testcases/merge.tig";
		StringBuffer sb = new StringBuffer();

		ErrorMsg errorMsg = new ErrorMsg(filename);
		InputStream inp = new FileInputStream(filename);
		Lexer lexer = new Lexer(inp, errorMsg);
		Grm p = new Grm(lexer, errorMsg);
		translate.Frag f;
		try {
			java_cup.runtime.Symbol s = p.parse();
//			Print.Print print = new Print.Print(System.out);
//			print.prExp((Absyn.Exp)(s.value), 0);
			semant.Semant sm = new semant.Semant(errorMsg);
			new FindEscape((Exp)s.value);
			f = sm.transProgram((Exp)s.value);
			if (!errorMsg.anyErrors) { 
				tree.Print ptr = new tree.Print(System.out);
				while (f != null) {
//					System.out.println("========= NEXT ==========");
					if (f instanceof translate.ProcFrag) {
//						ptr.prStm(((translate.ProcFrag)f).body);
						mips.Frame frm = (mips.Frame)(((translate.ProcFrag)f).frame);
						tree.StmList sl = canon.Canon.linearize(((translate.ProcFrag)f).body);
//						for (tree.StmList i = sl; i != null; i = i.tail) {
//						ptr.prStm(i.head);
//						}
						canon.BasicBlocks bb = new canon.BasicBlocks(sl);
//						canon.StmListList sll = bb.blocks;
//						for (canon.StmListList j = sll; j != null; j = j.tail) {
//						System.out.println("!!BLOCK!!");
//						for (tree.StmList i = j.head; i != null; i = i.tail)
//						ptr.prStm(i.head);
//						}
						canon.TraceSchedule ts = new canon.TraceSchedule(bb);
//						System.out.println("---------Trace----------");
//						for (tree.StmList i = ts.stms; i != null; i = i.tail)
//						ptr.prStm(i.head);
						assem.InstrList il = ((mips.Frame)((translate.ProcFrag)f).frame).generateCode(ts.stms);
//						temp.DefaultMap dm = new temp.DefaultMap();
						regAlloc.RegAlloc ra = new regAlloc.RegAlloc(((translate.ProcFrag)f).frame, il);
						mips.Proc prc = frm.procEntryExit3(il);
						System.out.println(prc.getGeneratedCode(ra));
//						flowGraph.AssemFlowGraph fg = new flowGraph.AssemFlowGraph(il);
//						fg.show(System.out);
//						regAlloc.Liveness ln = new regAlloc.Liveness(fg);
					}
					else {
						translate.DataFrag df = (translate.DataFrag)f;
						sb.append("\n\t.data\n");
						sb.append(df.label + ":\n");
						sb.append("\t.word\t" + df.str.length() + "\n");
						sb.append("\t.ascii\t\"");
						char a[] = df.str.toCharArray();
						for (int i = 0; i < a.length; i++)
							switch (a[i]) {
							case '\n' : sb.append("\\n");break;
							case '\t' : sb.append("\\t");break;
							case '\\' : sb.append("\\\\");break;
							case '\"' : sb.append("\\\"");break;
							default : sb.append(a[i]);
							}
						sb.append("\"\n");
						sb.append("\t.align\t2\n");
						sb.append("\t.text\n");

//						System.out.println(((translate.DataFrag)f).str);
					}
					f = f.next;
				}
				System.out.println(sb.toString());
			}


		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
